<div class="content guide with-sidebar single-file-components-guide">
<h1>单文件组件</h1>
<h2 id="介绍"><a class="headerlink" href="#介绍" title="介绍"></a>介绍</h2><p>在很多 Vue 项目中，我们使用 <code>Vue.component</code> 来定义全局组件，紧接着用 <code>new Vue({ el: '#container '})</code> 在每个页面内指定一个容器元素。</p>
<p>这种方式在很多中小规模的项目中运作的很好，在这些项目里 JavaScript 只被用来加强特定的视图。但当在更复杂的项目中，或者你的前端完全由 JavaScript 驱动的时候，下面这些缺点将变得非常明显：</p>
<ul>
<li><strong>全局定义 (Global definitions)</strong> 强制要求每个 component 中的命名不得重复</li>
<li><strong>字符串模板 (String templates)</strong> 缺乏语法高亮，在 HTML 有多行的时候，需要用到丑陋的 <code>\</code></li>
<li><strong>不支持 CSS (No CSS support)</strong> 意味着当 HTML 和 JavaScript 组件化时，CSS 明显被遗漏</li>
<li><strong>没有构建步骤 (No build step)</strong> 限制只能使用 HTML 和 ES5 JavaScript,  而不能使用预处理器，如 Pug (formerly Jade) 和 Babel</li>
</ul>
<p>文件扩展名为 <code>.vue</code> 的 <strong>single-file components(单文件组件)</strong> 为以上所有问题提供了解决方法，并且还可以使用 webpack 或 Browserify 等构建工具。</p>
<p>这是一个文件名为 <code>Hello.vue</code> 的简单实例：</p>
<p><a href="https://gist.github.com/chrisvfritz/e2b6a6110e0829d78fa4aedf7cf6b235" rel="noopener noreferrer" target="_blank"><img src="https://cn.vuejs.org/images/vue-component.png" style="display: block; margin: 30px auto;"/></a></p>
<p>现在我们获得：</p>
<ul>
<li><a href="https://github.com/vuejs/awesome-vue#source-code-editing" rel="noopener" target="_blank">完整语法高亮</a></li>
<li><a href="https://webpack.js.org/concepts/modules/#what-is-a-webpack-module" rel="noopener" target="_blank">CommonJS 模块</a></li>
<li><a href="https://vue-loader.vuejs.org/zh-cn/features/scoped-css.html" rel="noopener" target="_blank">组件作用域的 CSS</a></li>
</ul>
<p>正如我们说过的，我们可以使用预处理器来构建简洁和功能更丰富的组件，比如 Pug，Babel (with ES2015 modules)，和 Stylus。</p>
<p><a href="https://gist.github.com/chrisvfritz/1c9f2daea9bc078dcb47e9a82e5f7587" rel="noopener noreferrer" target="_blank"><img src="https://cn.vuejs.org/images/vue-component-with-preprocessors.png" style="display: block; margin: 30px auto;"/></a></p>
<p>这些特定的语言只是例子，你可以只是简单地使用 Babel，TypeScript，SCSS，PostCSS - 或者其他任何能够帮助你提高生产力的预处理器。如果搭配 <code>vue-loader</code> 使用 webpack，它也能为 CSS Modules 提供头等支持。</p>
<h3 id="怎么看待关注点分离？"><a class="headerlink" href="#怎么看待关注点分离？" title="怎么看待关注点分离？"></a>怎么看待关注点分离？</h3><p>一个重要的事情值得注意，<strong>关注点分离不等于文件类型分离。</strong>在现代 UI 开发中，我们已经发现相比于把代码库分离成三个大的层次并将其相互交织起来，把它们划分为松散耦合的组件再将其组合起来更合理一些。在一个组件里，其模板、逻辑和样式是内部耦合的，并且把他们搭配在一起实际上使得组件更加内聚且更可维护。</p>
<p>即便你不喜欢单文件组件，你仍然可以把 JavaScript、CSS 分离成独立的文件然后做到热重载和预编译。</p>
<pre><code class="hljs html"><span class="hljs-comment">&lt;!-- my-component.vue --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">template</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>This will be pre-compiled<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">template</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./my-component.js"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"./my-component.css"</span>&gt;</span><span class="undefined"></span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span></code></pre>
<h2 id="起步"><a class="headerlink" href="#起步" title="起步"></a>起步</h2><h3 id="例子沙箱"><a class="headerlink" href="#例子沙箱" title="例子沙箱"></a>例子沙箱</h3><p>如果你希望深入了解并开始使用单文件组件，请来 CodeSandbox <a href="https://codesandbox.io/s/o29j95wx9" rel="noopener" target="_blank">看看这个简单的 todo 应用</a>。</p>
<h3 id="针对刚接触-JavaScript-模块开发系统的用户"><a class="headerlink" href="#针对刚接触-JavaScript-模块开发系统的用户" title="针对刚接触 JavaScript 模块开发系统的用户"></a>针对刚接触 JavaScript 模块开发系统的用户</h3><p>有了 <code>.vue</code> 组件，我们就进入了高级 JavaScript 应用领域。如果你没有准备好的话，意味着还需要学会使用一些附加的工具：</p>
<ul>
<li><p><strong>Node Package Manager (NPM)</strong>：阅读 <a href="https://docs.npmjs.com/getting-started/what-is-npm" rel="noopener" target="_blank">Getting Started guide</a> 直到 <em>10: Uninstalling global packages</em>章节。</p>
</li>
<li><p><strong>Modern JavaScript with ES2015/16</strong>：阅读 Babel 的 <a href="https://babeljs.io/docs/learn-es2015/" rel="noopener" target="_blank">Learn ES2015 guide</a>。你不需要立刻记住每一个方法，但是你可以保留这个页面以便后期参考。</p>
</li>
</ul>
<p>在你花一天时间了解这些资源之后，我们建议你参考 <a href="https://cli.vuejs.org/zh/" rel="noopener" target="_blank">Vue CLI 3</a>。只要遵循指示，你就能很快地运行一个带有 <code>.vue</code> 组件、ES2015、webpack 和热重载 (hot-reloading) 的 Vue 项目!</p>
<h3 id="针对高级用户"><a class="headerlink" href="#针对高级用户" title="针对高级用户"></a>针对高级用户</h3><p>CLI 会为你搞定大多数工具的配置问题，同时也支持细粒度自定义<a href="https://cli.vuejs.org/zh/config/" rel="noopener" target="_blank">配置项</a>。</p>
<p>有时你会想从零搭建你自己的构建工具，这时你需要通过 <a href="https://vue-loader.vuejs.org/zh/" rel="noopener" target="_blank">Vue Loader</a> 手动配置 webpack。关于学习更多 webpack 的内容，请查阅<a href="https://webpack.js.org/configuration/" rel="noopener" target="_blank">其官方文档</a> 和 <a href="https://webpack.academy/p/the-core-concepts" rel="noopener" target="_blank">Webpack Academy</a>。</p>
<div class="guide-links">
<span>← <a href="filters.html">过滤器</a></span>
<span style="float: right;"><a href="unit-testing.html">单元测试</a> →</span>
</div>
<div class="footer">
<script src="//m.servedby-buysellads.com/monetization.js" type="text/javascript"></script>
<div class="bsa-cpc"></div>
<script>
  (function(){
    if(typeof _bsa !== 'undefined' && _bsa) {
    _bsa.init('default', 'CKYD62QM', 'placement:vuejsorg', {
      target: '.bsa-cpc',
      align: 'horizontal',
      disable_css: 'true'
    });
      }
  })();
</script>

    发现错误？想参与编辑？
    <a href="https://github.com/vuejs/cn.vuejs.org/blob/master/srcsingle-file-components.md" target="_blank">
      在 GitHub 上编辑此页！
    </a>
</div>
</div>